package org.aspire.game;

/******************************************************************************
 * Class to manage timing to create game independent of frame rate. <code>
 * Timer</code> is usually used to create sprite behavior, such as used in 
 * sprite animation.
 * <p>
 * 
 * Example how to use timer in conjunction with sprite in order to make the
 * sprite do an action every 1 second :
 * 
 * <pre>
 * public class DummySprite extends Sprite {
 *     Timer timer = new Timer(1000);
 *     public void update(long elapsedTime) {
 *       if (timer.action(elapsedTime)) {
 *         // do an action!! this always called every 1 second
 *       }
 *     }
 *   }
 * }
 * </pre>
 * 
 * @author Golden T Studios (GTGE)
 *****************************************************************************/
public class Timer extends Entity {

	// ========================================================================
	// Constants
	// ========================================================================

	// ========================================================================
	// Static Methods
	// ========================================================================

	// ========================================================================
	// Fields
	// ========================================================================

	/**************************************************************************
	 * Whether or not this timer is active. By disabling this, the timer will
	 * not be updated and the action will not be triggered.
	 * 
	 * Default: true
	 *************************************************************************/
	private boolean active;
	
	/**************************************************************************
	 * The amount of time, in milliseconds, that this timer will count.
	 *************************************************************************/
	private long delay;
	
	/**************************************************************************
	 * The current tick of the timer.
	 *************************************************************************/
	private long currentTick;
	
	// ========================================================================
	// Constructors
	// ========================================================================

	/**************************************************************************
	 * Construct a new timer with the specified delay.
	 * 
	 * @param delay the specified delay.
	 *************************************************************************/
	public Timer(long delay) {
		this.delay = delay;
		this.active = true;
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================
	
	/**************************************************************************
	 * Returns whether this timer is currently active.
	 * 
	 * @return whether or not this timer is active.
	 *************************************************************************/
	public boolean isActive() {
		return active;
	}

	/**************************************************************************
	 * Returns the amount of time this timer will count.
	 * 
	 * @return the timer delay.
	 *************************************************************************/
	public long getDelay() {
		return delay;
	}

	/**************************************************************************
	 * Returns the current tick of the timer.
	 * 
	 * @return the current tick of the timer.
	 *************************************************************************/
	public long getCurrentTick() {
		return currentTick;
	}

	/**************************************************************************
	 * Sets this timer active state.
	 * 
	 * @param active whether or not this timer will be active.
	 *************************************************************************/
	public void setActive(boolean active) {
		this.active = active;
	}

	/**************************************************************************
	 * Sets the delay for this timer.
	 * 
	 * @param delay the amount of time this timer will count.
	 *************************************************************************/
	public void setDelay(long delay) {
		this.delay = delay;
	}

	/**************************************************************************
	 * Sets the current tick for this timer. 
	 * 
	 * @param currentTick the new current tick.
	 *************************************************************************/
	public void setCurrentTick(long currentTick) {
		this.currentTick = currentTick;
	}

	// ========================================================================
	// Override Methods
	// ========================================================================

	// ========================================================================
	// Methods
	// ========================================================================

	/**************************************************************************
	 * Update the timer. The timer will count the amount of time elapsed since
	 * last update until the specified delay is reached.
	 * 
	 * @param elapsedTime the amount time elapsed from last update.
	 * @return whether or not the specified delay is reached.
	 *************************************************************************/
	public boolean action(long elapsedTime) {
		if (this.active) {
			this.currentTick += elapsedTime;
			if (this.currentTick >= this.delay) {
				// time elapsed!
	             
				// currentTick = 0;
				// synch the current tick to make the next tick accurate
				this.currentTick -= this.delay;
	             
				return true;
			}
		}
	       
		return false;
	}

	/**************************************************************************
	 * Refresh the current tick back to zero.
	 *************************************************************************/
	public void refresh() {
		this.currentTick = 0;
	}
	
	/**************************************************************************
	 * Sets this timer equal to the specified timer.
	 * 
	 * @param other the specified timer.
	 *************************************************************************/
	public void setEquals(Timer other) {
		this.active = other.active;
		this.delay = other.delay;
		this.currentTick = other.currentTick;
	}
	
	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}